import express from "express";
import cors from "cors";
import fileUpload from "express-fileupload";
import path from "node:path";
import { dirname } from "dirname-filename-esm";
import { promises as fs } from "fs";
import fse from "fs-extra";
import { createWriteStream, createReadStream } from "fs";
import { existsSync, mkdirSync } from "fs";

const app = express();
// 获取当前目录路径
const __dirname = dirname(import.meta);

// 配置目录路径
const UPLOAD_DIR = path.resolve(__dirname, "target");
const TEMP_DIR = path.resolve(__dirname, "temp");

existsSync(UPLOAD_DIR) || mkdirSync(UPLOAD_DIR);
existsSync(TEMP_DIR) || mkdirSync(TEMP_DIR);

app.use(cors());
app.use(express.json());
app.use(
  fileUpload({
    useTempFiles: true, // 启用临时文件
    tempFileDir: TEMP_DIR, // 明确指定目录
  })
);

// 上传分片
app.post("/upload", async (req, res) => {
  try {
    const { hash, index } = req.body;
    const chunk = req.files.chunk;
    const chunkDir = path.resolve(TEMP_DIR, hash);
    if (!fse.existsSync(chunkDir)) {
      await fs.mkdir(chunkDir);
    }
    const chunkPath = path.resolve(chunkDir, `${hash}-${index}`);
    await chunk.mv(chunkPath);
    res.json({ success: true });
  } catch (error) {
    console.error("上传分片出错:", error);
    res.status(500).json({ success: false });
  }
});

// 合并分片
app.post("/merge", async (req, res) => {
  try {
    const { hash } = req.body;
    const chunkDir = path.resolve(TEMP_DIR, hash);
    const targetPath = path.resolve(UPLOAD_DIR, hash);
    const chunks = await fs.readdir(chunkDir);
    // 按分片索引排序
    chunks.sort((a, b) => a.split("-")[1] - b.split("-")[1]);
    // 创建写入流
    const writeStream = createWriteStream(targetPath);

    for (const chunk of chunks) {
      const chunkPath = path.resolve(chunkDir, chunk);
      const readStream = createReadStream(chunkPath);
      await new Promise((resolve, reject) => {
        readStream.pipe(writeStream, { end: false });
        readStream.on("end", async () => {
          await fs.unlink(chunkPath);
          resolve(true);
        });
        readStream.on("error", reject);
      });
    }
    writeStream.end();
    await fs.rmdir(chunkDir);
    res.json({ success: true });
  } catch (error) {
    console.error("合并分片出错:", error);
    res.status(500).json({ success: false });
  }
});

app.listen(3000, () => {
  console.log("Server is running on port 3000");
});
